package com.znufe.exam.controller.admin;

import com.github.pagehelper.PageInfo;
import com.znufe.exam.base.BaseApiController;
import com.znufe.exam.base.RestResponse;
import com.znufe.exam.base.SystemCode;
import com.znufe.exam.configuration.config.annotation.Log;
import com.znufe.exam.configuration.config.enums.BusinessType;
import com.znufe.exam.domain.*;
import com.znufe.exam.domain.course.CoursePageResponseObject;
import com.znufe.exam.service.*;
import com.znufe.exam.utility.FileHandleUtil;
import com.znufe.exam.utility.PageInfoHelper;
import com.znufe.exam.utility.VideoUtil;
import com.znufe.exam.viewmodel.admin.course.CourseBindPaperRequestVm;
import com.znufe.exam.viewmodel.admin.course.CourseCreateVm;
import com.znufe.exam.viewmodel.admin.course.CoursePageResponseVm;
import com.znufe.exam.viewmodel.admin.subCourse.SubCourseBindResponseVm;
import com.znufe.exam.viewmodel.student.course.CoursePageRequestVm;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author gong
 */
@Api(description="课程信息接口")
@RestController("AdminCourseController")
@RequestMapping(value = "/api/admin/course")
@AllArgsConstructor
public class CourseController extends BaseApiController {

    private final CourseService courseService;
    private final SubCourseService subCourseService;
    private final ExamPaperService examPaperService;
    private final CourseSubCourseService courseSubCourseService;
    private final CourseExamPaperService courseExamPaperService;

    /**
     * @explain 管理端：新建课程与修改课程信息
     * @param courseCreateVm
     * @return
     */
    @PreAuthorize("@ss.hasAnyPermi('courses:courseli:add,courses:courseli:update')")
    @Log(title = "课程管理",businessType = BusinessType.EDIT)
    @PostMapping("/edit")
    @ApiOperation(value = "管理端：新建课程与修改课程信息",
                  notes = "新增/更新课程信息（更新请传入课程id）")
    public RestResponse<Course> edit(@RequestBody @Valid CourseCreateVm courseCreateVm){
        //前端传来的参数没有ID,说明想新建课程
        if(courseCreateVm.getId() == null){
            Course existCourse = courseService.getCourseByProjectAndNameAndType(courseCreateVm.getCourseProject(),
                    courseCreateVm.getCourseName(),courseCreateVm.getCourseType());
            //判断课程是否存在
            if(null != existCourse){
                return new RestResponse<>(421,"课程已存在");
            }
        }
        Course newCourse = modelMapper.map(courseCreateVm,Course.class);
        //新建课程
        if(courseCreateVm.getId() == null){
            newCourse.setGmtCreate(new Date());
            newCourse.setIsDeleted(0);
            newCourse.setStatus(0);
            courseService.insertSelective(newCourse);
            //找到新建的课程
            Course thisCourse = courseService.getCourseByProjectAndNameAndType(courseCreateVm.getCourseProject(),
                    courseCreateVm.getCourseName(),courseCreateVm.getCourseType());
            //为课程添加视频
            if(courseCreateVm.getSubCourseList() != null){
                List<Integer> subCourseList = courseCreateVm.getSubCourseList();
                //判断是否有重复
                long count = subCourseList.stream().distinct().count();
                if (subCourseList.size() != count){
                    return RestResponse.fail(SystemCode.DuplicateElement.getCode(),SystemCode.DuplicateElement.getMessage());
                }
                for (int i = 0;i<subCourseList.size();i++){
                    int subCourseId = subCourseList.get(i);
                    CourseSubCourse scs = new CourseSubCourse();
                    scs.setCourseId(thisCourse.getId());
                    scs.setSubCourseId(subCourseId);
                    scs.setGmtCreate(new Date());
                    courseSubCourseService.insertSelective(scs);
                }
            }
        }else {
            courseSubCourseService.deleteByCourseId(courseCreateVm.getId());
            if(courseCreateVm.getSubCourseList() != null){
                List<Integer> subCourseList = courseCreateVm.getSubCourseList();
                //判断是否有重复
                long count = subCourseList.stream().distinct().count();
                if (subCourseList.size() != count){
                    return RestResponse.fail(SystemCode.DuplicateElement.getCode(),SystemCode.DuplicateElement.getMessage());
                }
                for (int i = 0;i<subCourseList.size();i++){
                    int subCourseId = subCourseList.get(i);
                    CourseSubCourse scs = new CourseSubCourse();
                    scs.setCourseId(courseCreateVm.getId());
                    scs.setSubCourseId(subCourseId);
                    scs.setGmtCreate(new Date());
                    courseSubCourseService.insertSelective(scs);
                }
            }
            newCourse.setGmtModified(new Date());
            courseService.updateByPrimaryKeySelective(newCourse);
        }
        return RestResponse.ok(newCourse);
    }

    @PreAuthorize("@ss.hasPermi('courses:courseli:bind')")
    @Log(title = "课程管理", businessType = BusinessType.OTHER)
    @PostMapping("/bindExamPaper")
    @ApiOperation(value = "课程绑定试卷",notes = "传入试卷ID数组")
    public RestResponse bindExamPaper(@RequestBody CourseBindPaperRequestVm requestVm){
        courseExamPaperService.deleteByCourseId(requestVm.getId());
        try{
            List<Integer> examPaperList = requestVm.getExamPaperList();
            //判断是否有重复
            long count = examPaperList.stream().distinct().count();
            if (examPaperList.size() != count){
                return RestResponse.fail(SystemCode.DuplicateElement.getCode(),SystemCode.DuplicateElement.getMessage());
            }
            for (int i = 0;i<examPaperList.size();i++){
                CourseExamPaper cep = new CourseExamPaper();
                cep.setCourseId(requestVm.getId());
                cep.setExamPaperId(examPaperList.get(i));
                cep.setGmtCreate(new Date());

                int reg = courseExamPaperService.insertSelective(cep);
                if (reg <= 0){
                    return RestResponse.fail(SystemCode.InsertDataFail.getCode(),SystemCode.InsertDataFail.getMessage());
                }
            }
            return RestResponse.ok("绑定成功");
        }catch (Exception e){
            return RestResponse.fail(SystemCode.InnerError.getCode(),SystemCode.InnerError.getMessage());
        }
    }

    /**
     * @explain 管理端：根据课程ID获取课程信息
     * @param id
     * @return
     */
    @PreAuthorize("@ss.hasPermi('courses:courseli:query')")
    @RequestMapping(value = "/select/{id}", method = RequestMethod.GET)
    @ApiOperation(value = "管理端：点击编辑课程",notes = "根据课程ID获取课程信息")
    @ApiImplicitParam(paramType="path", name = "id", value = "课程ID", dataType = "int",required = true)
    public RestResponse<Course> select(@PathVariable Integer id){
        try{
            Course course = courseService.selectByPrimaryKey(id);
            if(course != null){
                return RestResponse.ok(course);
            }else {
                return RestResponse.fail(SystemCode.NoDataExist.getCode(),SystemCode.NoDataExist.getMessage());
            }
        }catch (Exception e){
            return RestResponse.fail(SystemCode.InnerError.getCode(),SystemCode.InnerError.getMessage());
        }
    }

    @RequestMapping(value = "/getBindSubCourse/{id}",method = RequestMethod.GET)
    @ApiOperation(value = "管理端：获取课程绑定的视频",notes = "参数为课程ID")
    public RestResponse getBindSubCourse(@PathVariable("id") Integer id){
        //获取绑定的视频ID
        List<Integer> subCourseIds = courseSubCourseService.getAllSubCourseId(id);
        if (subCourseIds.size() == 0){
            return RestResponse.ok(Collections.emptyList());
        }
        //根据视频ID列表获取视频
        List<SubCourse> subCourseList = subCourseService.getSubCourseByIds(subCourseIds);
        List<SubCourseBindResponseVm> responseVmList = subCourseList.stream().map(d -> {
            SubCourseBindResponseVm vm = modelMapper.map(d,SubCourseBindResponseVm.class);
            return vm;
        }).collect(Collectors.toList());
        return RestResponse.ok(responseVmList);
    }

    @RequestMapping(value = "/getBindExamPaper/{id}",method = RequestMethod.GET)
    @ApiOperation(value = "管理端：获取课程绑定的所有试卷")
    public RestResponse<List<ExamPaper>> getBindExamPaper(@PathVariable("id") Integer id){
        List<Integer> idList = courseExamPaperService.getAllExamPaperId(id);
        if (idList.size() == 0){
            return RestResponse.ok(Collections.emptyList());
        }else {
            List<ExamPaper> paperList = examPaperService.getAllExamPaperListById(idList);
            return RestResponse.ok(paperList);
        }
    }

    /**
     * @explain 管理端：删除课程，is_deleted字段设为1，实际是update
     * @param   id
     * @return  int
     * @author  bot
     * @time    Course
     */
    @PreAuthorize("@ss.hasPermi('courses:courseli:delete')")
    @Log(title = "课程管理", businessType = BusinessType.DELETE)
    @GetMapping("/delete/{id}")
    @ApiOperation(value = "管理端：删除课程")
    public RestResponse<Integer> delete(@PathVariable Integer id){
        try {
            int reg=courseService.deleteByPrimaryKey(id);
            if (reg>0) {
                return RestResponse.ok(reg);
            } else {
                return RestResponse.fail(SystemCode.DeleteDataFail.getCode(),SystemCode.DeleteDataFail.getMessage());
            }
        } catch (Exception e) {
            return RestResponse.fail(SystemCode.InnerError.getCode(),SystemCode.InnerError.getMessage());
        }
    }

    /**
     * @explain 管理端：分页显示课程信息+搜索
     * @param requestVM
     * @return
     */
    @PreAuthorize("@ss.hasPermi('courses:courseli:list')")
    @RequestMapping(value = "/coursePage",method = RequestMethod.POST)
    @ApiOperation(value = "管理端：分页显示课程信息+搜索")
    public RestResponse<PageInfo<CoursePageResponseVm>> courseList(@RequestBody CoursePageRequestVm requestVM){
        try {
            requestVM.setCourseName(requestVM.getCourseName().trim());
            PageInfo<CoursePageResponseObject> pageInfo = courseService.coursePage(requestVM);
            PageInfo<CoursePageResponseVm> page = PageInfoHelper.copyMap(pageInfo, d -> CoursePageResponseVm.from(d));
            return RestResponse.ok(page);
        }catch (Exception e){
            return RestResponse.fail(SystemCode.InnerError.getCode(),SystemCode.InnerError.getMessage());
        }
    }

    /**
     * @explain 管理端：修改课程状态
     * @param id
     * @return
     */
    @PreAuthorize("@ss.hasPermi('courses:courseli:update')")
    @Log(title = "课程管理", businessType = BusinessType.UPDATE)
    @RequestMapping(value = "/changeStatus/{id}",method = RequestMethod.GET)
    @ApiOperation(value = "管理端：修改课程状态")
    public RestResponse<Integer> changeStatus(@PathVariable Integer id) {
        try {
            Course course = courseService.selectByPrimaryKey(id);
            if (course != null) {
                Integer newStatus = course.getStatus() == 1 ? 0 : 1;
                course.setStatus(newStatus);
                course.setGmtModified(new Date());
                int reg = courseService.updateByIdFilter(course);
                if (reg > 0) {
                    return RestResponse.ok(newStatus);
                } else {
                    return RestResponse.fail(SystemCode.UpdateDataFail.getCode(), SystemCode.UpdateDataFail.getMessage());
                }
            } else {
                return RestResponse.fail(SystemCode.NoDataExist.getCode(), SystemCode.NoDataExist.getMessage());
            }
        }catch (Exception e){
            return RestResponse.fail(SystemCode.InnerError.getCode(),SystemCode.InnerError.getMessage());
        }
    }

    /**
     * @explain 上传课程封面
     * @param uploadFile
     * @return
     */
    @PostMapping("/courseCoverUpload")
    @ApiOperation(value = "管理端：为课程上传封面",
                  notes = "返回数据库存放地址（字符串），随表单一起提交")
    public RestResponse<String> courseCoverUpload(MultipartFile uploadFile){
        boolean flag = false;
        try{
            if (uploadFile.isEmpty()){
                return RestResponse.fail(SystemCode.FileEmptyError.getCode(),SystemCode.FileEmptyError.getMessage());
            }
            String oldName = uploadFile.getOriginalFilename();
            if (VideoUtil.checkPhotoSize(uploadFile)){
                if (VideoUtil.checkPhotoType(oldName)){
                    flag = true;
                }else {
                    return RestResponse.fail(SystemCode.FileFormatError.getCode(),SystemCode.FileFormatError.getMessage());
                }
            }else {
                return RestResponse.fail(SystemCode.FileSizeError.getCode(),SystemCode.FileSizeError.getMessage());
            }
            if (flag == true){
                String newName = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf("."));
                String filePath = FileHandleUtil.upload(uploadFile.getInputStream(), "video/", newName);
                return RestResponse.ok(filePath);
            }else {
                return RestResponse.fail(400,"图片上传失败");
            }

        }catch (Exception e){
            e.printStackTrace();
        }
        return RestResponse.fail(400,"文件上传失败");
    }

}
